package cn.iocoder.yudao.module.erp.service.invoiceintegration;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRejectReqVO;
import cn.iocoder.yudao.module.bpm.service.task.BpmTasktooServiceImpl;
import cn.iocoder.yudao.module.erp.controller.admin.checkout.vo.CheckOutRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.invoiceintegration.vo.InvoiceIntegrationPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.invoiceintegration.vo.InvoiceIntegrationRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.invoiceintegration.vo.InvoiceIntegrationSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.invoiceintegration.InvoiceIntegrationDO;
import cn.iocoder.yudao.module.erp.dal.mysql.invoiceintegration.InvoiceIntegrationMapper;
import com.alibaba.excel.util.StringUtils;
import jakarta.annotation.Resource;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.INVOICE_INTEGRATION_NOT_EXISTS;

/**
 * 发票整合 Service 实现类
 *
 * @author ls
 */
@Service
@Validated
public class InvoiceIntegrationServiceImpl implements InvoiceIntegrationService {

    @Resource
    private InvoiceIntegrationMapper invoiceIntegrationMapper;
    @Resource
    private BpmProcessInstanceApi processInstanceApi;

    @Autowired
    private BpmTasktooServiceImpl bpmTasktooService;


    /** 采购申请对应的流程定义KEY   */
    @Value("${erp.invoice.processKey}")
    private String PROCESS_KEY;

    /** 发票审核名   */
    @Value("${erp.invoice.taskname1}")
    private String PROCESS_Name1;

    /** 院办审核名   */
    @Value("${erp.invoice.taskname3}")
    private String PROCESS_Name3;


    @Override
    public String createInvoiceIntegration(InvoiceIntegrationSaveReqVO createReqVO) {
        // 插入
        InvoiceIntegrationDO invoiceIntegration = BeanUtils.toBean(createReqVO, InvoiceIntegrationDO.class);
        invoiceIntegrationMapper.insert(invoiceIntegration);
        // 返回
        return invoiceIntegration.getId();
    }

    @Override
    public void updateInvoiceIntegration(InvoiceIntegrationSaveReqVO updateReqVO) {
        // 校验存在
        validateInvoiceIntegrationExists(updateReqVO.getId());
        // 更新
        InvoiceIntegrationDO updateObj = BeanUtils.toBean(updateReqVO, InvoiceIntegrationDO.class);
        invoiceIntegrationMapper.updateById(updateObj);
    }

    @Override
    public void deleteInvoiceIntegration(String id) {
        // 校验存在
        validateInvoiceIntegrationExists(id);
        // 删除
        invoiceIntegrationMapper.deleteById(id);
    }

    private void validateInvoiceIntegrationExists(String id) {
        if (invoiceIntegrationMapper.selectById(id) == null) {
            throw exception(INVOICE_INTEGRATION_NOT_EXISTS);
        }
    }

    @Override
    public InvoiceIntegrationDO getInvoiceIntegration(String id) {
        return invoiceIntegrationMapper.selectById(id);
    }

    @Override
    public PageResult<InvoiceIntegrationRespVO> getInvoiceIntegrationPage(InvoiceIntegrationPageReqVO pageReqVO) {

        List<Task> taskTodoPage;
        PageResult<InvoiceIntegrationRespVO> respVOS= new PageResult<>();

//        1 为发票待审核 获取待办数据
        if ("1".equals(pageReqVO.getFlag())){

            taskTodoPage = bpmTasktooService.getTaskTodoToo(getLoginUserId(), PROCESS_Name1);
            // 检查 taskTodoPage 是否为空
            if (taskTodoPage == null || taskTodoPage.isEmpty()) {
                return respVOS;
            }
            //        把taskTodoPage集合中所有数据的process_instance_id提取出来成一个集合
            List<String> processInstanceIds = taskTodoPage.stream().map(Task::getProcessInstanceId).collect(Collectors.toList());
            pageReqVO.setProcessInstanceIds(processInstanceIds);
            PageResult<InvoiceIntegrationDO> invoiceIntegrationDOPageResult = invoiceIntegrationMapper.selectPage(pageReqVO);
            //        把taskTodoPage集合中的taskId设置到checkOutRespVO中
            respVOS = BeanUtils.toBean(invoiceIntegrationDOPageResult, InvoiceIntegrationRespVO.class);
            for (InvoiceIntegrationRespVO invoiceIntegrationRespVO : respVOS.getList()) {
                for (Task processInstanceId : taskTodoPage) {
                    if (invoiceIntegrationRespVO.getProcessInstanceId().equals(processInstanceId.getProcessInstanceId())) {
                        invoiceIntegrationRespVO.setTaskId(processInstanceId.getId());
                    }
                }
            }
//            2 院办审核页面
        } else if ("2".equals(pageReqVO.getFlag())){
            taskTodoPage = bpmTasktooService.getTaskTodoToo(getLoginUserId(), PROCESS_Name3);
            // 检查 taskTodoPage 是否为空
            if (taskTodoPage == null || taskTodoPage.isEmpty()) {
                return respVOS;
            }
            //        把taskTodoPage集合中所有数据的process_instance_id提取出来成一个集合
            List<String> processInstanceIds = taskTodoPage.stream().map(Task::getProcessInstanceId).collect(Collectors.toList());
            pageReqVO.setProcessInstanceIds(processInstanceIds);
            PageResult<InvoiceIntegrationDO> invoiceIntegrationDOPageResult = invoiceIntegrationMapper.selectPage(pageReqVO);
            //        把taskTodoPage集合中的taskId设置到checkOutRespVO中
            respVOS = BeanUtils.toBean(invoiceIntegrationDOPageResult, InvoiceIntegrationRespVO.class);
            for (InvoiceIntegrationRespVO invoiceIntegrationRespVO : respVOS.getList()) {
                for (Task processInstanceId : taskTodoPage) {
                    if (invoiceIntegrationRespVO.getProcessInstanceId().equals(processInstanceId.getProcessInstanceId())) {
                        invoiceIntegrationRespVO.setTaskId(processInstanceId.getId());
                    }
                }
            }
        } else if ("0".equals(pageReqVO.getFlag())) {
            PageResult<InvoiceIntegrationDO> invoiceIntegrationDOPageResult = invoiceIntegrationMapper.selectPage(pageReqVO);
            respVOS = BeanUtils.toBean(invoiceIntegrationDOPageResult, InvoiceIntegrationRespVO.class);
        }



        return respVOS;
    }

    @Override
    public void updateStatusByCheckInvoiceId(String checkInvoiceId, String invoiceStatus, String taskId,String approvalOpinion) {

        //        调用工作流的审批方法  通过

        if ("3".equals(invoiceStatus)){  // 通过
            BpmTaskApproveReqVO bpmTaskApproveReqVO = new BpmTaskApproveReqVO();
            bpmTaskApproveReqVO.setId(taskId);
            bpmTaskApproveReqVO.setReason(approvalOpinion);
            bpmTasktooService.approveTaskToo(getLoginUserId(),bpmTaskApproveReqVO);
        }else if ("2".equals(invoiceStatus)){  // 不通过
            BpmTaskRejectReqVO bpmTaskRejectReqVO = new BpmTaskRejectReqVO();
            bpmTaskRejectReqVO.setId(taskId);
            bpmTaskRejectReqVO.setReason(approvalOpinion);
            bpmTasktooService.rejectTaskToo(getLoginUserId(),bpmTaskRejectReqVO);
        }
        invoiceIntegrationMapper.updateStatusByCheckInvoiceId(checkInvoiceId, invoiceStatus);
    }

    @Override
    public void updatePayStatusByCheckInvoiceId(String checkInvoiceId, String payStatus,String taskId,String approvalOpinion) {
        //        调用工作流的审批方法  通过

        if ("3".equals(payStatus)){  // 通过
            BpmTaskApproveReqVO bpmTaskApproveReqVO = new BpmTaskApproveReqVO();
            bpmTaskApproveReqVO.setId(taskId);
            bpmTaskApproveReqVO.setReason(approvalOpinion);
            bpmTasktooService.approveTaskToo(getLoginUserId(),bpmTaskApproveReqVO);
        }else if ("2".equals(payStatus)){  // 不通过
            BpmTaskRejectReqVO bpmTaskRejectReqVO = new BpmTaskRejectReqVO();
            bpmTaskRejectReqVO.setId(taskId);
            bpmTaskRejectReqVO.setReason(approvalOpinion);
            bpmTasktooService.rejectTaskToo(getLoginUserId(),bpmTaskRejectReqVO);
        }
        invoiceIntegrationMapper.updatePayStatusByCheckInvoiceId(checkInvoiceId, payStatus);
    }

    @Override
    public void sendInvoiceIntegration(String id) {
        InvoiceIntegrationDO invoiceIntegrationDO = invoiceIntegrationMapper.selectById(id);
        /**
         * -------将业务插入到工作流程表中测试---
        **/
        if(!StringUtils.isEmpty(PROCESS_KEY)) {
            // 发起 BPM 流程  加这里
            Map<String, Object> processInstanceVariables = new HashMap<>();
            // processInstanceVariables.put("day", PROCESS_KEY);
            String processInstanceId = processInstanceApi.createProcessInstance(getLoginUserId(),
                    new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
                            .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(invoiceIntegrationDO.getId()))
                            .setStartUserSelectAssignees(null));

            // 将工作流的编号，更新到 OA 请假单中
            invoiceIntegrationMapper.updateById(new InvoiceIntegrationDO().setId(invoiceIntegrationDO.getId()).setProcessInstanceId(processInstanceId));

        }
    }

}